package com.org.shichui.util;

import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtils {

    /**
     * 给指定日期增加n天，如果n为负数则减少n天
     *
     * @param date
     * @param n
     * @return
     */
    public static Date addDay(Date date, int n) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, n);
        return cd.getTime();
    }

    /**
     * 给指定日期增加n天，如果n为负数则减少n天
     *
     * @param dateStr
     * @param n
     * @return
     */
    public static String addDay(String dateStr, int n) {
        Date date = StringToDate(dateStr);
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, n);
        return dateToStr(cd.getTime());
    }

    /**
     * 将日期转换成yyyy-MM-dd形式的字符串
     *
     * @param date
     * @return
     */
    public static String dateToStr(Date date) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(date);
    }

    /**
     * 将日期转换成指定形式的字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateToStr(Date date, String format) {
        DateFormat df = new SimpleDateFormat(format);
        if (date == null) {
            return "";
        }
        return df.format(date);
    }

    /**
     * 字符串转换到时间格式
     *
     * @param dateStr
     * @return
     */
    public static Date StringToDate(String dateStr) {
        DateFormat dd = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = dd.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 字符串转换到时间格式
     *
     * @param dateStr
     * @param formatStr yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Date StringToDate(String dateStr, String formatStr) {
        DateFormat dd = new SimpleDateFormat(formatStr);
        Date date = null;
        try {
            date = dd.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * @param @param  line 包含el表达式的字符串
     * @param @param  map	el表达式中具体的值
     * @param @return
     * @return String 解析后的字符串
     * @throws
     * @Title: setRtexprvalue
     * @Description: el表达式替换具体值
     */
    public static String setRtexprvalue(String line, Map<String, String> map) {
        String regex = "\\$\\{([^\\}]+)\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(line);
        String key = "";
        while (matcher.find()) {
            key = matcher.group(1);
            line = matcher.replaceFirst(map.get(key) + "");
            matcher = pattern.matcher(line);
        }
        return line;
    }

    /**
     * @param @param  line
     * @param @return
     * @return List<String>
     * @throws
     * @Title: getRtexprkeys
     * @Description: 获取el表达式中的变量
     */
    public static List<String> getRtexprkeys(String line) {
        String regex = "\\$\\{([^\\}]+)\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(line);
        List<String> keys = null;
        while (matcher.find()) {
            if (keys == null) {
                keys = new ArrayList<String>();
            }
            String key = matcher.group(1);
            keys.add(key);
        }
        return keys;
    }

    /**
     * 本地图片转换成base64编码
     *
     * @param filename
     * @return
     * @throws IOException
     */
    public static String getImageString(String filename) {
        File file = new File(filename);
        if (!file.exists()) {
            return "";
        }
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(filename);
            data = new byte[in.available()];
            in.read(data);
            in.close();
            Base64.Encoder encoder = Base64.getEncoder();
            return data != null ? encoder.encodeToString(data) : "";
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 返回项目根路径
     *
     * @return
     */
    public static String rootPath() {
        String path = Thread.currentThread().getContextClassLoader().getResource("").getPath().substring(1);
        File file = new File(path);
        return file.getParentFile().getParent();
    }

    /**
     * 网络图片保存到本地
     *
     * @param httpPath
     * @param filePath
     * @throws IOException
     */
    public static void getImageForhttp(String httpPath, String filePath, String fileName) {
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        int BUFFER_SIZE = 1024;
        byte[] buf = new byte[BUFFER_SIZE];
        int size = 0;
        try {
            url = new URL(httpPath);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            fos = new FileOutputStream(filePath + "/" + fileName);
            while ((size = bis.read(buf)) != -1) {
                fos.write(buf, 0, size);
            }
            fos.flush();
        } catch (IOException e) {
        } catch (ClassCastException e) {
        } finally {
            try {
                fos.close();
                bis.close();
                httpUrl.disconnect();
            } catch (IOException e) {
            } catch (NullPointerException e) {
            }
        }
    }

    /**
     * 删除文件夹
     *
     * @param folderPath
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文件夹下的类容
     *
     * @param path
     * @return
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /**
     * @param @param  str
     * @param @param  formatstr yyyy-MM-dd HH:mm:ss
     * @param @return
     * @return boolean
     * @throws
     * @Title: isValidDate
     * @Description: 判断字符串是否是时间格式
     */
    public static boolean isValidDate(String str, String formatstr) {
        boolean convertSuccess = true;
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
        SimpleDateFormat format = new SimpleDateFormat(formatstr);
        try {
            // 设置lenient为false.
            // 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            convertSuccess = false;
        }
        return convertSuccess;
    }

    /**
     * @param @param  source
     * @param @param  target
     * @param @throws IllegalArgumentException
     * @param @throws IllegalAccessException
     * @return void
     * @throws
     * @Title: iceCopy
     * @Description: 将ICE对象的数据copy到java标准对象
     */
    public static <T, K> void iceCopy(T source, K target) throws IllegalArgumentException, IllegalAccessException {
        Field[] sourceFields = source.getClass().getFields();
        Field[] targetFields = target.getClass().getDeclaredFields();
        for (Field field : sourceFields) {
            Object o = field.get(source);
            String fieldName = field.getName();
            for (Field field2 : targetFields) {
                if (fieldName.equals(field2.getName())) {
                    field2.setAccessible(true);
                    if (o instanceof String) {
                        if (isValidDate(o.toString(), "yyyy-MM-dd HH:mm:ss")) {
                            Date date = StringToDate(o.toString(), "yyyy-MM-dd HH:mm:ss");
                            field2.set(target, date);
                            break;
                        }
                    }
                    field2.set(target, o);
                    field2.setAccessible(false);
                    break;
                }
            }
        }
    }

    /**
     * @param @param  source
     * @param @param  target
     * @param @throws IllegalArgumentException
     * @param @throws IllegalAccessException
     * @return void
     * @throws
     * @Title: iceEntityCopy
     * @Description: 将java标准对象的数据copy到ice对象中
     */
    public static <T, K> void iceEntityCopy(T source, K target) throws IllegalArgumentException, IllegalAccessException {
        Field[] sourceFields = source.getClass().getDeclaredFields();
        Field[] targetFields = target.getClass().getFields();
        for (Field field : sourceFields) {
            field.setAccessible(true);
            Object o = field.get(source);
            String fieldName = field.getName();
            for (Field field2 : targetFields) {
                if (fieldName.equals(field2.getName())) {
                    field2.setAccessible(true);
                    if (o instanceof Date) {
                        String date = dateToStr((Date) o, "yyyy-MM-dd HH:mm:ss");
                        field2.set(target, date);
                        break;
                    }
                    field2.set(target, o);
                    field2.setAccessible(false);
                    break;
                }
            }
            field.setAccessible(false);
        }
    }

}
